package com.evil.common.es.dto.application.order.data;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.evil.common.application.dto.order.data.ControlDataValueDTO;
import com.evil.common.es.dto.application.order.ESOrderDataDTO;
import com.evil.common.es.util.ESFieldUtil;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.annotations.InnerField;
import org.springframework.data.elasticsearch.annotations.MultiField;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 控件值 ES实体
 *
 * @author liyang
 * @date 2022-08-08 00:00
 */
@Data
@Accessors(chain = true)
public class ESControlDataValueDTO {

    public static final String COL_ID = "id";
    public static final String COL_IDS = "ids";
    public static final String COL_VALUE = "value";
    public static final String COL_DV = "data_value";
    public static final String COL_DATA = "data";
    public static final String COL_DATE = "date";
    public static final String COL_EMAIL = "email";
    public static final String COL_ORDINAL = "ordinal";
    public static final String COL_OI = "other_info";
    public static final String COL_PV = "plugin_value";
    public static final String COL_SORT = "sort";

    public static final String COL_DN_V_ID = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_V, COL_ID);
    public static final String COL_DN_VN_ID = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_VN, COL_ID);

    public static final String COL_DN_V_IDS = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_V, COL_IDS);
    public static final String COL_DN_VN_IDS = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_VN, COL_IDS);

    public static final String COL_DN_V_VALUE = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_V, COL_VALUE);
    public static final String COL_DN_VN_VALUE = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_VN, COL_VALUE);
    public static final String COL_DN_V_VALUE_KEYWORD = ESFieldUtil.joinKeyword(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_V, COL_VALUE);
    public static final String COL_DN_VN_VALUE_KEYWORD = ESFieldUtil.joinKeyword(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_VN, COL_VALUE);

    public static final String COL_DN_V_DV_KEYWORD = ESFieldUtil.joinKeyword(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_V, COL_DV);
    public static final String COL_DN_V_DV = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_V, COL_DV);
    public static final String COL_DN_VN_DV_KEYWORD = ESFieldUtil.joinKeyword(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_VN, COL_DV);
    public static final String COL_DATA_NESTED_VN_DV = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_VN, COL_DV);
    public static final String COL_DN_TVN_V_DV_KEYWORD = ESFieldUtil.joinKeyword(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_TVN, ESControlDataDTO.COL_V, COL_DV);
    public static final String COL_DN_TVN_R_V_DV_KEYWORD = ESFieldUtil.joinKeyword(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_TVN, ESControlDataDTO.COL_R, ESControlDataDTO.COL_V, COL_DV);
    public static final String COL_DN_TVN_R_VN_DV_KEYWORD = ESFieldUtil.joinKeyword(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_TVN, ESControlDataDTO.COL_R, ESControlDataDTO.COL_VN, COL_DV);

    public static final String COL_DN_V_DATA = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_V, COL_DATA);
    public static final String COL_DN_VN_DATA = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_VN, COL_DATA);
    public static final String COL_DN_TVN_V_DATA = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_TVN, ESControlDataDTO.COL_V, COL_DATA);
    public static final String COL_DN_TVN_R_V_D = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_TVN, ESControlDataDTO.COL_R, ESControlDataDTO.COL_V, COL_DATA);
    public static final String COL_DN_TVN_R_VN_D = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_TVN, ESControlDataDTO.COL_R, ESControlDataDTO.COL_VN, COL_DATA);

    public static final String COL_DN_V_DATE = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_V, COL_DATE);
    public static final String COL_DN_VN_DATE = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_VN, COL_DATE);
    public static final String COL_DN_TVN_V_DATE = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_TVN, ESControlDataDTO.COL_V, COL_DATE);
    public static final String COL_DN_TVN_R_V_DATE = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_TVN, ESControlDataDTO.COL_R, ESControlDataDTO.COL_V, COL_DATE);
    public static final String COL_DN_TVN_R_VN_DATE = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_TVN, ESControlDataDTO.COL_R, ESControlDataDTO.COL_VN, COL_DATE);

    public static final String COL_DN_V_EMAIL = ESFieldUtil.joinKeyword(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_V, COL_EMAIL);
    public static final String COL_DN_VN_EMAIL = ESFieldUtil.joinKeyword(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_VN, COL_EMAIL);

    public static final String COL_DN_V_ORDINAL = ESFieldUtil.joinKeyword(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_V, COL_ORDINAL);
    public static final String COL_DN_VN_ORDINAL = ESFieldUtil.joinKeyword(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_VN, COL_ORDINAL);

    public static final String COL_DN_V_OI = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_V, COL_OI);
    public static final String COL_DN_VN_OI = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_VN, COL_OI);

    public static final String COL_DN_V_PV = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_V, COL_PV);
    public static final String COL_DN_VN_PV = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_VN, COL_PV);

    public static final String COL_DN_V_SORT = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_V, COL_SORT);
    public static final String COL_DN_VN_SORT = ESFieldUtil.join(ESOrderDataDTO.COL_DN, ESControlDataDTO.COL_VN, COL_SORT);
    /**
     * 选择项id
     */
    @Field(name = COL_ID, type = FieldType.Long)
    private Long id;
    /**
     * 选择项ids 单个数据 选择多个选项，比如级联选择 开启了多选
     */
    @Field(name = COL_IDS, type = FieldType.Long_Range)
    private List<Long> ids;
    /**
     * 值
     */
    @MultiField(mainField = @Field(name = COL_VALUE, type = FieldType.Text, fielddata = true),
            otherFields = {
                    @InnerField(suffix = "keyword", type = FieldType.Keyword, ignoreAbove = 256)
            }
    )
    private String value;
    /**
     * 值
     */
    @MultiField(mainField = @Field(name = COL_DV, type = FieldType.Text, fielddata = true),
            otherFields = {
                    @InnerField(suffix = "keyword", type = FieldType.Keyword, ignoreAbove = 256)
            }
    )
    private String dataValue;
    /**
     * 值
     */
    @Field(name = COL_DATA)
    private BigDecimal data;
    /**
     * 值（日期）
     */
    @Field(name = COL_DATE, type = FieldType.Date)
    private Date date;
    /**
     * 值（邮箱）
     */
    @Field(name = COL_EMAIL, type = FieldType.Text)
    private String email;
    /**
     * 字典
     */
    @Field(name = COL_ORDINAL, type = FieldType.Text)
    private String ordinal;
    /**
     * 其他信息
     */
    @Field(name = COL_OI, type = FieldType.Object)
    private Object otherInfo;
    /**
     * 值（插件）
     */
    @Field(name = COL_PV, type = FieldType.Text)
    private String pluginValue;
    /**
     * 序号
     */
    @Field(name = COL_SORT, type = FieldType.Integer)
    private Integer sort;

    public ESControlDataValueDTO() {
        this.sort = 0;
    }

    public ESControlDataValueDTO(ControlDataValueDTO controlDataValueDTO, Function<ControlDataValueDTO, String> getDataValue) {
        BeanUtil.copyProperties(controlDataValueDTO, this);
        this.dataValue = getDataValue.apply(controlDataValueDTO);
        this.sort = 0;
        this.data = BigDecimal.ZERO;
        if (Objects.nonNull(this.dataValue)) {
            try {
                this.data = new BigDecimal(this.dataValue);
            } catch (Exception ignored) {
            }
            try {
                this.date = DateUtil.parse(this.dataValue);
            } catch (Exception ignored) {
            }
        }
    }

    public static List<ESControlDataValueDTO> toESControlDataValueDTO(List<ControlDataValueDTO> controlDataValueDTOS,
                                                                      String controlCode,
                                                                      BiFunction<String, ControlDataValueDTO, String> getDataValue) {
        return controlDataValueDTOS.stream()
                .map(e -> new ESControlDataValueDTO(e, v -> getDataValue.apply(controlCode, v)))
                .collect(Collectors.toList());
    }

    public ControlDataValueDTO toControlDataValueDTO() {
        return BeanUtil.copyProperties(this, ControlDataValueDTO.class);
    }
}
